<template>
  <div>
    <div id="mask"></div>
    <div id="panel">
      <div id="title">
        <div>登录</div>
        <div
          @click="close()"
          id="close"
        >
          X
        </div>
      </div>
      <div id="content">
        <div id="user-input-panel">
          <div id="left-content">
            <el-input
              class="user-input"
              v-model="username"
              :placeholder="isUpdatePassword ? '请输入绑定的邮箱' : '请输入用户名'"
              autocomplete="username"
            />
            <el-input
              class="user-input"
              v-model="password"
              show-password
              placeholder="请输入密码"
            />
            <div
              id="qr-panel"
              class="user-input"
            >
              <el-input
                class="qr-input"
                v-model="qrcode"
                placeholder="请输入验证码"
              >
                <template #append>
                  <el-button
                    @click="changeQRCode"
                    :disabled="isDisabled"
                    >{{ isDisabled ? countDown : '获取' }}
                  </el-button>
                </template>
              </el-input>
              <img
                :src="qrcodeBase64 || ''"
                alt=""
              />
            </div>
          </div>
          <div id="right-content">
            <div
              class="wanning"
              :class="{ mark: isUpdatePassword ? emailCheck : usernameCheck }"
            >
              {{
                isUpdatePassword
                  ? '请使用邮箱进行修改密码'
                  : '用户名: 长度在 3 到 16 个字符之间。 只能包含字母（大小写）、数字、下划线 _ 和连字符 -。不能以下划线或连字符开头和结尾。'
              }}
            </div>
            <div
              class="wanning"
              :class="{ mark: passwordCheck }"
            >
              密码: 长度在 8 到 20 个字符之间。 至少包含一个大写字母。 至少包含一个小写字母。 至少包含一个数字。
              至少包含一个特殊字符（例如：!@#$%^&*）。 不允许包含空格。
            </div>
          </div>
        </div>
        <div class="user-input">
          {{ errorMessage }}
        </div>
        <div id="change">
          <a @click="changePanel">{{ isUpdatePassword ? '返回登录' : '忘记密码' }}</a>
        </div>
        <el-button
          id="summit"
          type="warning"
          round
          @click="loginService"
          >{{ isUpdatePassword ? '修改' : '登录/注册' }}
        </el-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import type { UserInfo } from '@/types/user'
import { computed } from 'vue'
import type { QRCodeVO, TokenVO, UnifyResponse } from '@/types/result'
import { useUserStore } from '@/stores/userStore.ts'
import { getQRCodeAPI, postLoginAPI, postUserVOAPI } from '@/services/userService.ts'
import { ApiException } from '@/utils/exception/api-exception.ts'

const emit = defineEmits(['close'])

const username = ref<string>('')
const password = ref<string>('')
const qrcode = ref<string>('')
const qrcodeBase64 = ref<string | null>('')
const countDown = ref<number>(5)
const isDisabled = ref<boolean>(false)
const isUpdatePassword = ref<boolean>(false)
const errorMessage = ref<string>('')
const sid = ref<number | null>(null)
const userdata: UserInfo = {
  username: '',
  password: '',
  qrcode: '',
}
const usernameRegex = /^(?!_|-)[a-zA-Z0-9_-]{3,16}(?<!_|-)$/
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{8,20}$/
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
const usernameCheck = computed((): boolean => {
  return usernameRegex.test(username.value)
})
const passwordCheck = computed((): boolean => {
  return passwordRegex.test(password.value)
})
const emailCheck = computed((): boolean => {
  return emailRegex.test(username.value)
})

function close() {
  emit('close', 0, false)
}

function changePanel() {
  username.value = ''
  password.value = ''
  qrcode.value = ''
  errorMessage.value = ''
  qrcodeBase64.value = ''
  isUpdatePassword.value = !isUpdatePassword.value
}

async function loginService() {
  if (!checkValid()) {
    errorMessage.value = '用户名或密码不正确'
    return
  }
  if (qrcode.value === '') {
    errorMessage.value = '验证码不能为空'
    return
  }
  userdata.username = username.value
  userdata.password = password.value
  userdata.qrcode = qrcode.value
  if (!isUpdatePassword.value) {
    try {
      const res: UnifyResponse<TokenVO> = await postLoginAPI(userdata)
      const userStore = useUserStore()
      userStore.token = res.data

      const userRes = await postUserVOAPI()
      userStore.userVO = userRes.data
      close()
    } catch (err) {
      if (err instanceof ApiException) {
        errorMessage.value = err.message
      } else {
        return Promise.reject(err)
      }
    }
  }
}

function checkValid() {
  return usernameRegex.test(username.value) && passwordRegex.test(password.value)
}

async function changeQRCode() {
  if (!checkValid()) {
    errorMessage.value = '请先输入正确的用户名及密码'
    return
  }
  userdata.username = username.value
  userdata.password = password.value
  userdata.qrcode = qrcode.value
  try {
    const res: UnifyResponse<QRCodeVO> = await getQRCodeAPI(userdata)
    qrcodeBase64.value = res.data
  } catch (err) {
    if (err instanceof ApiException) {
      errorMessage.value = err.message
    } else {
      return Promise.reject(err)
    }
  }
  isDisabled.value = true
  sid.value = setInterval(() => {
    if (countDown.value <= 0) {
      clearInterval(sid.value as number)
      countDown.value = 5
      isDisabled.value = false
      return
    }
    countDown.value -= 1
  }, 1000)
}
</script>

<style scoped>
#mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
}

#panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 40rem;
  height: 27rem;
  background-color: #c1bbbb;
  border-radius: 2rem;
}

#title {
  background-color: #535353;
  height: 3rem;
  border-radius: 2rem 2rem 0 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2rem 0 2rem;
  font-weight: bold;
  color: #74ba1d;
}

#close {
  cursor: pointer;
}

#content {
  margin-top: 2em;
  height: 20em;
  width: 100%;
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: space-around;
}

#user-input-panel {
  width: 100%;
  height: 15em;
  margin-bottom: 0.5em;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-around;
}

#left-content {
  height: 100%;
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: space-around;
  margin-left: 1em;
}

#right-content {
  width: 10em;
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: space-between;
  margin-right: 1em;
}

.user-input {
  width: 20rem;
  text-align: center;
  color: #cc1d1d;
}

#qr-panel {
  display: flex;
  justify-content: space-between;
}

.user-input .qr-input {
  width: 13em;
}

.user-input img {
  height: 2em;
  width: 8em;
  border: 1px solid #000000;
}

#change {
  width: 20em;
  text-align: right;
  color: #ffef8f;
}

#change a:hover {
  cursor: pointer;
  font-weight: bold;
}

#summit {
  width: 10em;
}

.wanning {
  font-size: 0.3em;
  margin-bottom: 3em;
  color: #ff0000;
}

.mark {
  color: #42ff4c;
}
</style>
